package com.cljz.peipei.ui.activity;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.cljz.peipei.R;
import com.cljz.peipei.base.BaseActivity;
import com.cljz.peipei.model.net.bean.GetUserInfoBean;
import com.cljz.peipei.model.net.bean.ResponseBean;
import com.cljz.peipei.present.activity.VideoCallP;
import com.cljz.peipei.utils.CommonUtils;
import com.cljz.peipei.utils.ConstellationUtils;
import com.cljz.peipei.utils.L;
import com.cljz.peipei.utils.T;
import com.cljz.peipei.widget.CameraSurfaceView;
import com.cljz.peipei.widget.FlagButton;
import com.cljz.peipei.widget.PeriscopeLayout;
import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMCallManager;
import com.hyphenate.chat.EMCallStateChangeListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMCmdMessageBody;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.exceptions.EMNoActiveCallException;
import com.hyphenate.exceptions.EMServiceNotReadyException;
import com.hyphenate.media.EMLocalSurfaceView;
import com.hyphenate.media.EMOppositeSurfaceView;
import com.jakewharton.rxbinding.view.RxView;
import com.superrtc.sdk.VideoView;

import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import cn.droidlover.xdroidmvp.kit.Kits;
import pl.droidsonroids.gif.GifImageView;
import rx.functions.Action1;

/**
 * Created by apple on 2017/5/9.
 */

public class VideoCallActivity extends BaseActivity<VideoCallP> implements EMCallStateChangeListener, EMMessageListener {

    @BindView(R.id.csv_camera)
    CameraSurfaceView csvCamera;
    @BindView(R.id.opposite_surface)
    EMOppositeSurfaceView oppositeSurface;
    @BindView(R.id.iv_say_bye)
    ImageView ivSayBye;
    @BindView(R.id.iv_label)
    ImageView ivLabel;
    @BindView(R.id.iv_time)
    ImageView ivTime;
    @BindView(R.id.tv_overlook)
    TextView tvOverlook;
    @BindView(R.id.btn_join_up)
    Button btnJoinUp;
    @BindView(R.id.ll_btn)
    LinearLayout llBtn;
    @BindView(R.id.giv_wait)
    GifImageView givWait;
    @BindView(R.id.fl_btn)
    FrameLayout flBtn;
    @BindView(R.id.tv_tag1)
    TextView tvTag1;
    @BindView(R.id.tv_tag2)
    TextView tvTag2;
    @BindView(R.id.tv_tag3)
    TextView tvTag3;
    @BindView(R.id.ll_tags)
    LinearLayout llTags;
    @BindView(R.id.tv_describe1)
    TextView tvDescribe;
    @BindView(R.id.tv_nickname)
    TextView tvNickname;
    @BindView(R.id.iv_sex)
    ImageView ivSex;
    @BindView(R.id.periscope)
    PeriscopeLayout periscope;
    @BindView(R.id.local_surface)
    EMLocalSurfaceView localSurface;
    @BindView(R.id.tv_count_down)
    TextView tvCountDown;
    @BindView(R.id.ll_local)
    LinearLayout llLocal;
    @BindView(R.id.rl_call_wait)
    RelativeLayout rlCallWait;
    private String userId;
    private String from;
    private AudioManager audioManager;
    private EMCallManager.EMVideoCallHelper callHelper;
    private PopupWindow byeWindow;
    private boolean isFirst = true;
    private int callTime = 25;
    private int addTime;
    private Boolean isFirstAddTime = true;
    private boolean hasClickAddTime = false;
    private boolean hasReceive = false;
    private int otherTime;
    private String result = "";
    private Intent resultIntent;
    private List<String> tags;

    @Override
    public void initData(Bundle savedInstanceState) {

        getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

        resultIntent = getIntent();
        //设置通话画面填充方式
        audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMicrophoneMute(false);
        EMClient.getInstance().callManager().addCallStateChangeListener(this);
        EMClient.getInstance().chatManager().addMessageListener(this);
        callHelper = EMClient.getInstance().callManager().getVideoCallHelper();
        localSurface.setZOrderMediaOverlay(true);
        localSurface.setZOrderOnTop(true);
        oppositeSurface.setScaleMode(VideoView.EMCallViewScaleMode.EMCallViewScaleModeAspectFill);
        localSurface.setScaleMode(VideoView.EMCallViewScaleMode.EMCallViewScaleModeAspectFill);
        //这个要设置在上面两个方法之后，不然会概率出现接收方无画面
        EMClient.getInstance().callManager().setSurfaceView(localSurface, oppositeSurface);
        rlCallWait.setVisibility(View.VISIBLE);
        givWait.setVisibility(View.GONE);
        userId = getIntent().getExtras().getString("userId");
        from = getIntent().getExtras().getString("from");
        getP().getUserInfoData(userId);
    }

    @Override
    protected void initListener() {
        super.initListener();
        RxView.clicks(btnJoinUp)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        handler.removeCallbacks(ignorRunnable);
                        if ("invite".equals(from)) {
                            llBtn.setVisibility(View.GONE);
                            givWait.setVisibility(View.VISIBLE);

                            //拨打视频电话
                            try {
                                EMClient.getInstance().callManager().makeVideoCall(userId);
                            } catch (EMServiceNotReadyException e) {
                                e.printStackTrace();
                            }
                        } else {
                            try {
                                EMClient.getInstance().callManager().answerCall();
                            } catch (EMNoActiveCallException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                });
        RxView.clicks(tvOverlook)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        try {
                            EMClient.getInstance().callManager().rejectCall();
                        } catch (EMNoActiveCallException e) {
                            e.printStackTrace();
                        } finally {
                            result = MainActivity.ACCORD_IGNORE;
                            resultIntent.putExtra("result", result);
                            setResult(RESULT_OK, resultIntent);
                            finish();
                            overridePendingTransition(R.anim.in, R.anim.out);

                        }
                    }
                });
        RxView.clicks(ivSayBye)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        initSayBye();
                    }
                });

        RxView.clicks(ivTime).throttleFirst(2, TimeUnit.SECONDS)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        hasClickAddTime = true;
                        if (isFirst) {
                            //获取当前剩下的时间，再加上
                            addTime = 30;
                            isFirst = false;
                        } else {
                            //直接加上60秒
                            addTime = 60;
                        }
                        //同时
                        EMMessage cmdMsg = EMMessage.createSendMessage(EMMessage.Type.CMD);
                        String time = tvCountDown.getText().toString().trim();
                        String synTime = time.substring(time.length() - 2, time.length());
                        EMCmdMessageBody cmdBody = new EMCmdMessageBody(synTime);
                        cmdMsg.addBody(cmdBody);
                        cmdMsg.setTo(userId);
//                        cmdMsg.setReceipt();
                        EMClient.getInstance().chatManager().sendMessage(cmdMsg);
                        periscope.addHeartEnd();
                        addVideoTime();
                    }
                });
    }

    private void addVideoTime() {
        if (hasClickAddTime && hasReceive) {
            if (isFirstAddTime) {
                int localTime = callTime / 10 % 10 + callTime % 10;
                if (localTime < otherTime) {
                    callTime = callTime - (callTime / 10 % 10 * 10 + callTime % 10) + otherTime + addTime;
                } else {
                    callTime = callTime + addTime;
                }
                isFirstAddTime = false;
            } else {
                callTime = callTime + addTime;
            }
            hasClickAddTime = false;
            hasReceive = false;
        }

    }

    /**
     * 开始通话计时，这里在全局管理器中开启一个定时器进行计时，可以做到最小化，以及后台时进行计时
     */
    Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            callTime--;
            if (callTime > 0) {
                handler.postDelayed(this, 1000);
                if (callTime <= 8) {
                    startShakeByViewAnim(ivTime, 0.9f, 1.1f, 10f, 1000);
                }
                refreshCallTime();
            } else {
                try {
                    getP().callEnd();
                    EMClient.getInstance().callManager().endCall();
                } catch (EMNoActiveCallException e) {
                    e.printStackTrace();
                } finally {
                    resultIntent.putExtra("result", result);
                    setResult(RESULT_OK, resultIntent);
                    finish();
                    overridePendingTransition(R.anim.in, R.anim.out);

                }
            }
        }
    };

    private int ignorTime = 10;
    Runnable ignorRunnable = new Runnable() {
        @Override
        public void run() {
            ignorTime--;
            handler.postDelayed(this, 1000);
            if (ignorTime == 0) {
                try {
                    EMClient.getInstance().callManager().rejectCall();
                } catch (EMNoActiveCallException e) {
                    e.printStackTrace();
                } finally {
                    //自动忽略
                    result = MainActivity.AUTO_IGNORE;
                    resultIntent.putExtra("result", result);
                    setResult(RESULT_OK, resultIntent);
                    finish();
                    overridePendingTransition(R.anim.in, R.anim.out);

                }
            }
        }
    };


    //    **
//            * 刷新通话时间显示
//     */
    private void refreshCallTime() {
        int t = callTime;
        int h = t / 60 / 60;
        int m = t / 60 % 60;
        int s = t % 60 % 60;
        String time = "";
        if (h > 9) {
            time = "" + h;
        } else {
            time = "0" + h;
        }
        if (m > 9) {
            time += ":" + m;
        } else {
            time += ":0" + m;
        }
        if (s > 9) {
            time += ":" + s;
        } else {
            time += ":0" + s;
        }
        if (!tvCountDown.isShown()) {
            tvCountDown.setVisibility(View.VISIBLE);
        }
        tvCountDown.setText(time);
    }

    private void startShakeByViewAnim(View view, float scaleSmall, float scaleLarge, float shakeDegrees, long duration) {
        if (view == null) {
            return;
        }
        //TODO 验证参数的有效性

        //由小变大
        Animation scaleAnim = new ScaleAnimation(scaleSmall, scaleLarge, scaleSmall, scaleLarge);
        //从左向右
        Animation rotateAnim = new RotateAnimation(-shakeDegrees, shakeDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        scaleAnim.setDuration(duration);
        rotateAnim.setDuration(duration / 10);
        rotateAnim.setRepeatMode(Animation.REVERSE);
        rotateAnim.setRepeatCount(10);

        AnimationSet smallAnimationSet = new AnimationSet(false);
        smallAnimationSet.addAnimation(scaleAnim);
        smallAnimationSet.addAnimation(rotateAnim);

        view.startAnimation(smallAnimationSet);
    }

    private void initSayBye() {
        View sayByeView = LayoutInflater.from(this).inflate(R.layout.pop_bye, null);
        LinearLayout llScare = (LinearLayout) sayByeView.findViewById(R.id.ll_scare);
        LinearLayout llAngry = (LinearLayout) sayByeView.findViewById(R.id.ll_angry);
        LinearLayout llCool = (LinearLayout) sayByeView.findViewById(R.id.ll_cool);
        if (byeWindow == null) {
            byeWindow = new PopupWindow();
        }
        byeWindow.setContentView(sayByeView);
        byeWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
        byeWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
        byeWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        byeWindow.setFocusable(true);
        byeWindow.setOutsideTouchable(true);
        byeWindow.setTouchable(true);
        //更新PopupWindow状态，如果当前已是显示状态，就从当前状态更新
        byeWindow.update();
        byeWindow.showAsDropDown(ivSayBye, Kits.Dimens.dpToPxInt(this, -55), Kits.Dimens.dpToPxInt(this, 10));
        RxView.clicks(llScare)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        byeWindow.dismiss();
                        endCall();
                        //结束了以后，应该重新进行匹配
                    }
                });
        RxView.clicks(llAngry)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        byeWindow.dismiss();
                        endCall();
                    }
                });
        RxView.clicks(llCool)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        byeWindow.dismiss();
                        endCall();
                    }
                });

    }

    private void endCall() {
        try {
            EMClient.getInstance().callManager().endCall();
        } catch (EMNoActiveCallException e) {
            e.printStackTrace();
        } finally {
            closeSpeakerOn();
            resultIntent.putExtra("result", result);
            setResult(RESULT_OK, resultIntent);
            finish();
            overridePendingTransition(R.anim.in, R.anim.out);

        }
    }

    @Override
    public int getLayoutId() {
        return R.layout.activity_video_call;
    }

    // 打开扬声器
    protected void openSpeakerOn() {
        try {
            if (!audioManager.isSpeakerphoneOn()) {
                // 打开扬声器
                audioManager.setSpeakerphoneOn(true);
            }
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void closeSpeakerOn() {

        try {
            if (audioManager != null) {
                // int curVolume =
                // audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
                if (audioManager.isSpeakerphoneOn()) {
                    audioManager.setSpeakerphoneOn(false);
                }
                audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
                // audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
                // curVolume, AudioManager.STREAM_VOICE_CALL);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public VideoCallP newP() {
        return new VideoCallP();
    }

    public void getUserInfoSucceed(GetUserInfoBean getUserInfoBean) {
        tvNickname.setText(getUserInfoBean.getData().getNickname());
        tags = getUserInfoBean.getData().getTag();
        if (tags.size() == 0) {
            llTags.setVisibility(View.GONE);
        } else {
            if (tags.size() == 1) {
                llTags.setVisibility(View.VISIBLE);
                tvTag1.setText(tags.get(0));
                tvTag2.setVisibility(View.GONE);
                tvTag3.setVisibility(View.GONE);
            } else if (tags.size() == 2) {
                llTags.setVisibility(View.VISIBLE);
                tvTag1.setText(tags.get(0));
                tvTag2.setText(tags.get(1));
                tvTag3.setVisibility(View.GONE);
            } else {
                llTags.setVisibility(View.VISIBLE);
                tvTag1.setText(tags.get(0));
                tvTag2.setText(tags.get(1));
                tvTag3.setText(tags.get(2));
            }
        }
        // TODO tvDescribe 显示用户星座
        if ("1".equals(getUserInfoBean.getData().getSex())) {
            ivSex.setImageResource(R.mipmap.male);
            tvDescribe.setText("有一位" + getUserInfoBean.getData().getAge() + "岁的小哥哥正在向你招手");
        } else if ("0".equals(getUserInfoBean.getData().getSex())) {
            ivSex.setImageResource(R.mipmap.female);
            tvDescribe.setText("有一位" + getUserInfoBean.getData().getAge() + "岁的美少女正在向你招手");
        }
        tvDescribe.setText(ConstellationUtils.getConstellation(Integer.valueOf(getUserInfoBean.getData().getConstellation())));
        rlCallWait.setVisibility(View.VISIBLE);
        givWait.setVisibility(View.GONE);
        handler.postDelayed(ignorRunnable, 1000);

    }
    public void getUserInfoSucceed2(GetUserInfoBean getUserInfoBean) {
        List<String> tags = getUserInfoBean.getData().getTag();
        if (tags.size() == 0) {
            llTags.setVisibility(View.GONE);
        } else {
            if (tags.size() == 1) {
                llTags.setVisibility(View.VISIBLE);
                tvTag1.setText(tags.get(0));
                tvTag2.setVisibility(View.GONE);
                tvTag3.setVisibility(View.GONE);
            } else if (tags.size() == 2) {
                llTags.setVisibility(View.VISIBLE);
                tvTag1.setText(tags.get(0));
                tvTag2.setText(tags.get(1));
                tvTag3.setVisibility(View.GONE);
            } else {
                llTags.setVisibility(View.VISIBLE);
                tvTag1.setText(tags.get(0));
                tvTag2.setText(tags.get(1));
                tvTag3.setText(tags.get(2));
            }
        }
        rlCallWait.setVisibility(View.GONE);
        givWait.setVisibility(View.GONE);
        ivSex.setVisibility(View.GONE);
        tvNickname.setVisibility(View.GONE);
    }
    public void getUserInfoFail(String error) {

    }

    @Override
    protected void setScreen() {
        //WindowManager是Android中一个重要的服务（Service ）。WindowManager Service 是全局的，是唯一的
        //WindowManager.LayoutParams 是 WindowManager 接口的嵌套类；它继承于 ViewGroup.LayoutParams；
        // 它用于向WindowManager描述Window的管理策略。
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        //窗口显示时，隐藏所有的屏幕装饰（例如状态条）。使窗口占用整个显示区域。
        lp.flags = (WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setAttributes(lp);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }

    @Override
    public void onCallStateChanged(CallState callState, CallError callError) {
        switch (callState) {
            case CONNECTING: // 正在连接对方

                break;
            case CONNECTED: // 双方已经建立连接

                break;

            case ACCEPTED: // 电话接通成功
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        getP().callSuccess();
                        csvCamera.setVisibility(View.GONE);
                        rlCallWait.setVisibility(View.GONE);
                        llLocal.setVisibility(View.VISIBLE);
                        ivSayBye.setVisibility(View.VISIBLE);
                        ivLabel.setVisibility(View.VISIBLE);
                        ivTime.setVisibility(View.VISIBLE);
                        //点击显示对方标签
                        ivLabel.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                            showTagView();
                            }
                        });
                        openSpeakerOn();
                        handler.postDelayed(runnable, 1000);
                    }
                });
                break;
            case DISCONNECTED: // 电话断了
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
//                        T.getInstance().showShort("对方已挂断");
                        closeSpeakerOn();
                        getP().callEnd();
                        resultIntent.putExtra("result", result);
                        setResult(RESULT_OK, resultIntent);
                        finish();
                        overridePendingTransition(R.anim.in, R.anim.out);
                    }
                });
                break;
            case NETWORK_UNSTABLE: //网络不稳定
                if (callError == CallError.ERROR_NO_DATA) {
                    //无通话数据
                } else {
                }
                break;
            case NETWORK_NORMAL: //网络恢复正常

                break;
            default:
                break;
        }
    }

    private void showTagView() {
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.pop_tagscall, null);
        LinearLayout layout = (LinearLayout)view.findViewById(R.id.linear);
        FrameLayout flClose = (FrameLayout)view.findViewById(R.id.fl_close);

        View inflate;
        if (tags != null ) {
            for (int i = 0; i < tags.size(); i++) {
                inflate = inflater.inflate(R.layout.item_have_chosen, null);
                TextView tv = (TextView) inflate.findViewById(R.id.tv_tag);
                ImageView iv = (ImageView) inflate.findViewById(R.id.iv_delete);
                iv.setVisibility(View.GONE);
                tv.setText(tags.get(i));
                layout.addView(inflate);
            }
        }

        final PopupWindow tagsWindow = new PopupWindow(view, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, true);
        tagsWindow.setTouchable(true);
        ColorDrawable dw = new ColorDrawable(0xb0000000);
        tagsWindow.setBackgroundDrawable(dw);
        tagsWindow.showAtLocation(oppositeSurface, Gravity.CENTER | Gravity.CENTER_HORIZONTAL, 0, 0);

        RxView.clicks(flClose)
                .compose(this.<Void>bindToLifecycle())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        tagsWindow.dismiss();
                    }
                });


    }

    @Override
    public void onMessageReceived(List<EMMessage> list) {

    }

    @Override
    public void onCmdMessageReceived(List<EMMessage> messages) {
        for (int i = 0; i < messages.size(); i++) {
            L.e(messages.get(i).getBody().toString());
        }
        String cmd = CommonUtils.getNumbers(messages.get(0).getBody().toString());
        L.e("收到透传消息：" + cmd);
        if (cmd.length() == 2) {
            hasReceive = true;
            otherTime = Integer.parseInt(cmd);
            addVideoTime();
        }
    }

    @Override
    public void onMessageRead(List<EMMessage> list) {

    }

    @Override
    public void onMessageDelivered(List<EMMessage> list) {

    }

    @Override
    public void onMessageChanged(EMMessage emMessage, Object o) {

    }

    public void callEndSucceed(ResponseBean responseBean) {

    }

    public void callEndFail(String error) {

    }

    @Override
    protected void onDestroy() {
        handler.removeCallbacksAndMessages(null);
        EMClient.getInstance().callManager().removeCallStateChangeListener(this);
        callHelper.stopVideoRecord();
        localSurface.getRenderer().dispose();
        localSurface = null;
        oppositeSurface.getRenderer().dispose();
        oppositeSurface = null;
        csvCamera.destroyCamera();
        csvCamera =null;
//        localSurface.release();
//        oppositeSurface.release();
        super.onDestroy();

    }

    public void callSucceed(ResponseBean responseBean) {

    }

    public void callFail(String error) {

    }
}